package com.ruoyi.framework.web.service;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.RegexConstant;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.user.*;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MailUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.email.Mail;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.SysUpdatePassword;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.util.RandomVerifyCode;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class SysUpdatePasswordService {
    @Autowired
    private ISysUserService userService;
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private MailUtil mailUtil;

//    private final String verifyPassword = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[\\W_]).{9,}$";

    /**
     * 验证邮箱
     *
     * @return
     */
    public AjaxResult checkEmail(SysUpdatePassword updatePassword) {

        System.out.println(updatePassword);
        //使用工具生成uuid
        String uuid = IdUtils.simpleUUID();
        //根据用户名查找用户
        SysUser sysUser = userService.selectUserByUserName(updatePassword.getUsername());
        //用户不存在异常
        if (Objects.isNull(sysUser)) {
            throw new UserException("user.not.exist", null);
        }
        //邮箱不匹配异常
        if (!updatePassword.getEmail().equals(sysUser.getEmail())) {
            throw new EmailNotMatchException();
        }
        AjaxResult ajax = new AjaxResult(200, "邮箱验证成功");
        //随机生成6位数验证码
        String code = RandomVerifyCode.generateSixDigitRandomNumber();

        //发送验证码到指定邮箱

        Mail mail = new Mail();
        mail.setRecipient(sysUser.getEmail());
        mail.setSubject("修改密码，邮箱验证");
        mail.setContent("亲爱的用户：您好！\n" +
                "\n" + "    您收到这封电子邮件是因为您 (也可能是某人冒充您的名义) 申请了修改直通车密码。假如这不是您本人所申请, 请不用理会这封电子邮件, 但是如果您持续收到这类的信件骚扰, 请您尽快联络管理员。\n" +
                "\n" +
                "   请使用以下验证码完成后续修改密码流程\n" + "\n  " +
                code + "\n\n" + "  注意：请您收到邮件的五分钟内（" +
                DateFormatUtils.format(new Date().getTime() + 5 * 60 * 1000, "yyyy-MM-dd HH:mm:ss") +
                "）前使用，否则验证码将会失效。");


        mailUtil.sendSimpleMail(mail);

        //把验证码存到redis中，key是email_verify_code:uuid
        String verifyKey = CacheConstants.EMAIL_VERIFY_KEY + StringUtils.nvl(uuid, "");
        redisCache.setCacheObject(verifyKey, code, 5, TimeUnit.MINUTES);

        System.out.println("验证码键为：key=【" + verifyKey + "】验证码为：code=【" + code+"】");
//        String code2 = redisCache.getCacheObject(verifyKey);
//        System.out.println("code2 = " + code2);
//        System.out.println(code.equals(code2));
        ajax.put("uuid", uuid);
        return ajax;
    }

    /**
     * 修改密码
     *
     * @return
     */
    public AjaxResult updatePwd(SysUpdatePassword updatePassword) {
        AjaxResult ajaxResult = new AjaxResult(200, "密码修改成功");
        System.out.println("updatePassword = " + updatePassword);

        //根据uuid获取验证码
        String uuid = updatePassword.getUuid();
        //如果uuid为null或者是空字符串，则抛出验证码失效异常
        if (StringUtils.isEmpty(uuid)) {
            throw new CaptchaExpireException();
        }
        String verifyKey = CacheConstants.EMAIL_VERIFY_KEY + StringUtils.nvl(uuid, "");
        String code = redisCache.getCacheObject(verifyKey);
        //与前端发过来的uuid进行匹配，如果不匹配，则抛出异常

        if (!code.equals(updatePassword.getCode())) {
            throw new CaptchaException();
        }

        //对前端发过来的密码进行校验，是否符合要求
        if (!updatePassword.getPassword().matches(RegexConstant.VERIFY_PASSWORD)) {
            throw new UserException("user.password.not.valid", null);
        }

        SysUser sysUser = userService.selectUserByUserName(updatePassword.getUsername());
        String newPassword = updatePassword.getPassword();
        String oldPassword = sysUser.getPassword();
        //判断用户密码是否和原先的密码一致
        if (SecurityUtils.matchesPassword(newPassword, oldPassword)) {
            throw new UserException("user.newPassword.not.update", null);
        }


        //修改用户密码，使用工具类对密码进行加密
        sysUser.setPassword(SecurityUtils.encryptPassword(updatePassword.getPassword()));

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(DateUtils.getNowDate());
        calendar.add(Calendar.DAY_OF_YEAR, 90);
        sysUser.setForceUpdatePasswordTime(calendar.getTime());

        userService.updateUser(sysUser);

        //把验证码的缓存删除,减少内存压力
        redisCache.deleteObject(verifyKey);
        return ajaxResult;
    }
}
